/**
 * 
 */
package com.xpec.c4.game.datamanager.agent.money;

import java.io.Serializable;
import java.math.BigDecimal;
import java.util.ArrayList;
import java.util.Iterator;
import java.util.Map;

import com.ms.game.itembox.GameDropItemParam;
import com.ms.game.itembox.ItemChangeParam;
import com.ms.game.itembox.db.ItemChangeProcessData;
import com.ms.game.itembox.db.PlayerCrystalChangeLogModel;
import com.ms.game.itembox.db.PlayerItemChangeLogModel;
import com.ms.player.PlayerUserType;
import com.ms.player.UpdateAttribute;
import com.ms.service.error.ErrorCode;
import com.xpec.c4.db.model.log.basic.BasicLogModel;
import com.xpec.c4.game.utility.GUID;
import com.xpec.c4.message.ConstantCode;

/**
 * 透過 dc 變更角色金錢的相關參數
 * 
 * @author TW15010
 */
public class MoneyChangeParam implements Serializable {

	private static final long serialVersionUID = 7591082771754829217L;

	public static final BigDecimal NO_JACKPOT = BigDecimal.ZERO;
	
	/** 交易id */
	private GUID orderId;

	/** 要變更的幣別和數值清單 */
	private ChangeCoinLister changeCoinLister;
	
	/** 遊戲中獲得道具資料 */
	private GameDropItemParam dropItemParam;
	
	/** 道具驗證後的資料*/
	private ItemChangeProcessData itemChangeProcessData;
	
	/** 使用道具資料**/
	private ItemChangeParam itemChangeParam;

	/** 遊戲Type*/
	private String gameId;

	/** 遊戲名稱*/
	private String gameName;

	/** 遊戲館id */
	private String gameHallId;

	/** 遊戲館名 */
	private String gameHallName;
	
	/**
	 * 幣值比(一般初始狀況都維持1)<br>
	 * 註：此值是用來參考此金錢異動在何種比值下進行的，changeCoinLister中的值不需要再經過換算
	 */
	private BigDecimal gainRate = BigDecimal.ONE;
	public BigDecimal getGainRate() { return gainRate; }
	public void setGainRate(BigDecimal gainRate) { this.gainRate = gainRate; }

	/** 行為id */
	private MoneyChangeWay changeWay;

	/** account guid */
	private GUID accountId;

	/** player guid */
	private GUID playerId;

	/** player name */
	private String playerName;

	/** 使用者類型 {@link PlayerUserType} */
	private int userType;

	/** 發出要求的 module id */
	private String srcModuleId;
	
	/** 是否是離線SPIN */
	private boolean isOfflineSpin;
	
	/** 發生時間 (毫秒)*/
	private long changeTime;
	
	/** 營運商 id */
	private String venderId;

	/** 子營運商 id */
	private String subVenderId;
	
	// 回傳資料區 ==================================

	/** 結果代碼 {@link ErrorCode} */
	private int result;

	/** 金錢變更後連帶影響的屬性清單 */
	private ArrayList<UpdateAttribute> updatedAttrList;

	/** 銀行的錢 */
	private BigDecimal bankGoldCoin;

	/** 角色身上金幣  **/
	private BigDecimal goldCoin;
	
	/**JP金額*/
	private BigDecimal jpScore;
	
	/** 是不是小樂*/
	private boolean isRobot;
	
	/** sessionId */
	private GUID sessionId;


	/**
	 * 取得 log 用的執行結果字串
	 * <p>
	 * 必須在有執行結果之後才呼叫
	 * 
	 * @return 執行結果字串
	 */
	public String getResultString() {
		StringBuilder sb = new StringBuilder();
		sb.append("change player(" + playerName + "|" + playerId + ") money " + changeWay.getDesc() + " ");

		if (result == ErrorCode.SUCCESS) {
			sb.append("success. ");
		} else {
			sb.append("fail(" + ConstantCode.getName(ErrorCode.class, result) + "). ");
		}

		ChangeCoinLister coinLister = getChangeCoinLister();
		Iterator<Map.Entry<CoinType, ChangeCoin>> it = coinLister.getListIterator();
		ChangeCoin coinInfo = coinLister.getNextCoin(it);
		while (coinInfo != null) {
			sb.append(coinInfo.getCoinType().getDesc() + " " + coinInfo.getChangeValue() + " "
					+ coinInfo.getCurrentValue() + " => " + coinInfo.getNewValue() + " res="
					+ ConstantCode.getName(ErrorCode.class, coinInfo.getResult()) + ". ");

			coinInfo = coinLister.getNextCoin(it);
		}

		if (changeWay.isDailyScore() && dropItemParam != null) {
			if (dropItemParam.getLogList().size() > 0) {
				sb.append("get item in game: ");
			}

			for (BasicLogModel log : dropItemParam.getLogList()) {
				if (log instanceof PlayerItemChangeLogModel) {
					PlayerItemChangeLogModel ilog = (PlayerItemChangeLogModel) log;
					sb.append(ilog.getItemId() + " " + ilog.getChangeCount() + " " + ilog.getBeforeChange()
							+ " => " + ilog.getAfterChange() + ". ");
				}

				if (log instanceof PlayerCrystalChangeLogModel) {
					PlayerCrystalChangeLogModel clog = (PlayerCrystalChangeLogModel) log;
					sb.append("crystal " + clog.getChangeCrystal() + " " + clog.getBeforeCrystal() + " => "
							+ clog.getAfterCrystal() + ". ");
				}
			}
		}

		sb.append("orderId=" + orderId.toString());

		return sb.toString();
	}

	
	public String getGameId() {
		return gameId;
	}

	public void setGameId(String gameId) {
		this.gameId = gameId;
	}
	
	public String getGameHallId() {
		return gameHallId;
	}

	public void setGameHallId(String gameHallId) {
		this.gameHallId = gameHallId;
	}

	public MoneyChangeWay getChangeWay() {
		return changeWay;
	}

	public void setChangeWay(MoneyChangeWay changeWay) {
		this.changeWay = changeWay;
	}

	public GUID getAccountId() {
		return accountId;
	}

	public void setAccountId(GUID accountId) {
		this.accountId = accountId;
	}

	public GUID getPlayerId() {
		return playerId;
	}

	public void setPlayerId(GUID playerId) {
		this.playerId = playerId;
	}

	public String getPlayerName() {
		return playerName;
	}

	public void setPlayerName(String playerName) {
		this.playerName = playerName;
	}

	public String getSrcModuleId() {
		return srcModuleId;
	}

	public void setSrcModuleId(String srcModuleId) {
		this.srcModuleId = srcModuleId;
	}

	public String getGameHallName() {
		return gameHallName;
	}

	public void setGameHallName(String gameHallName) {
		this.gameHallName = gameHallName;
	}

	public ChangeCoinLister getChangeCoinLister() {
		return changeCoinLister;
	}

	public void setChangeCoinLister(ChangeCoinLister changeCoinLister) {
		this.changeCoinLister = changeCoinLister;
	}

	public int getResult() {
		return result;
	}

	public void setResult(int result) {
		this.result = result;
	}

	public GUID getOrderId() {
		return orderId;
	}

	public void setOrderId(GUID orderId) {
		this.orderId = orderId;
	}

	public BigDecimal getBankGoldCoin() {
		return bankGoldCoin;
	}

	public void setBankGoldCoin(BigDecimal bankGoldCoin) {
		this.bankGoldCoin = bankGoldCoin;
	}

	public BigDecimal getGoldCoin() {
		return goldCoin;
	}

	public void setGoldCoin(BigDecimal goldCoin) {
		this.goldCoin = goldCoin;
	}
	
	public ArrayList<UpdateAttribute> getUpdatedAttrList() {
		return updatedAttrList;
	}

	public void setUpdatedAttrList(ArrayList<UpdateAttribute> updatedAttrList) {
		this.updatedAttrList = updatedAttrList;
	}

	public GameDropItemParam getDropItemParam() {
		return dropItemParam;
	}

	public void setDropItemParam(GameDropItemParam dropItemParam) {
		this.dropItemParam = dropItemParam;
	}
	
	public ItemChangeParam getItemChangeParam() {
		return itemChangeParam;
	}


	public void setItemChangeParam(ItemChangeParam itemChangeParam) {
		this.itemChangeParam = itemChangeParam;
	}


	public ItemChangeProcessData getItemChangeProcessData() {
		return itemChangeProcessData;
	}


	public void setItemChangeProcessData(ItemChangeProcessData itemChangeProcessData) {
		this.itemChangeProcessData = itemChangeProcessData;
	}


	public BigDecimal getJpScore() {
		return jpScore;
	}

	public void setJpScore(BigDecimal jpScore) {
		this.jpScore = jpScore;
	}
	
	public String getGameName() {
		return gameName;
	}

	public void setGameName(String gameName) {
		this.gameName = gameName;
	}


	public int getUserType() {
		return userType;
	}


	public void setUserType(int userType) {
		this.userType = userType;
	}


	public boolean isOfflineSpin() {
		return isOfflineSpin;
	}


	public void setOfflineSpin(boolean isOfflineSpin) {
		this.isOfflineSpin = isOfflineSpin;
	}


	public long getChangeTime() {
		return changeTime;
	}


	public void setChangeTime(long changeTime) {
		this.changeTime = changeTime;
	}
	

	public boolean isRobot() {
		return isRobot;
	}


	public void setRobot(boolean isRobot) {
		this.isRobot = isRobot;
	}


	public GUID getSessionId() {
		return sessionId;
	}


	public void setSessionId(GUID sessionId) {
		this.sessionId = sessionId;
	}
	public String getVenderId() {
		return venderId;
	}
	public void setVenderId(String venderId) {
		this.venderId = venderId;
	}
	public String getSubVenderId() {
		return subVenderId;
	}
	public void setSubVenderId(String subVenderId) {
		this.subVenderId = subVenderId;
	}

}